package com.hulman.oms.service;

import com.hulman.oms.bean.*;
import com.hulman.oms.dao.RepairDao;
import com.hulman.oms.exception.IoTException;
import com.hulman.oms.util.DateUtil;
import com.hulman.oms.util.OrderUtil;
import com.hulman.oms.util.SubjectUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @Author: maxwellens
 */
@Service
public class RepairService
{
    private static final String PROCESS_KEY = "repair";
    @Autowired
    private RepairDao repairDao;
    @Autowired
    private FaultService faultService;
    @Autowired
    private ProcInstService procInstService;
    @Autowired
    private UserService userService;
    @Autowired
    private TaskService taskService;
    @Autowired
    private MsgService msgService;

    public List<Repair> findRepairs(Map<String, Object> map)
    {
        return repairDao.findRepairs(map);
    }

    public Integer findRepairsCount(Map<String, Object> map)
    {
        return repairDao.findRepairsCount(map);
    }

    public Result findRepairsResult(Map<String, Object> map)
    {
        Integer page = (Integer) map.get("page");
        Integer limit = (Integer) map.get("limit");
        if (page != null && limit != null)
        {
            map.put("start", (page - 1) * limit);
            map.put("length", limit);
        }
        int count = repairDao.findRepairsCount(map);
        List<Repair> data = repairDao.findRepairs(map);
        return new Result(data, count);
    }

    public Repair findRepairById(Integer id)
    {
        return repairDao.findRepairById(id);
    }

    public Repair findRepairByFaultId(Integer faultId)
    {
        return repairDao.findRepairByFaultId(faultId);
    }

    public void deleteRepairById(Integer id)
    {
        repairDao.deleteRepairById(id);
    }

    public void deleteRepairs(int[] ids)
    {
        repairDao.deleteRepairs(ids);
    }

    @Transactional(rollbackFor = Exception.class)
    public void create(Integer faultId, String content, Integer deviceId, String deviceName, String deviceLocation, String directorName)
    {
        User user = SubjectUtil.getUser();
        if (user == null)
        {
            throw new IoTException("用户未登陆");
        }
        //创建工单
        ProcInst procInst = procInstService.startProcess(PROCESS_KEY);
        Repair repair = new Repair();
        repair.setProcInstId(procInst.getId());
        repair.setNo(OrderUtil.generate("WX"));
        repair.setFaultId(faultId);
        repair.setContent(content);
        repair.setDeviceId(deviceId);
        repair.setDeviceName(deviceName);
        repair.setDeviceLocation(deviceLocation);
        repair.setCreateById(user.getId());
        repair.setCreateByName(user.getName());
        repair.setCreateTime(new Date());
        User director = userService.findUserByName(directorName);
        repair.setDirectorId(director.getId());
        repair.setDirectorName(director.getName());
        repair.setState(Repair.STATE_EXECUTING);
        repairDao.insertRepair(repair);
        //修改缺陷状态为“维修中”
        Fault fault = faultService.findFaultById(repair.getFaultId());
        fault.setRepairId(repair.getId());
        fault.setState(Fault.STATE_REPAIRING);
        faultService.saveFault(fault);

        Task thisTask = new Task();
        thisTask.setProcInstId(repair.getProcInstId());
        thisTask.setOwnerId(user.getId());
        thisTask.setOwnerName(user.getName());
        thisTask.setName(procInst.getStateName());
        thisTask.setTag(PROCESS_KEY);
        taskService.createAndCompleteTask(thisTask);

        //生成任务（发给负责人）
        procInst = procInstService.next(procInst.getId());
        Task task = new Task();
        task.setProcInstId(procInst.getId());
        task.setOwnerId(director.getId());
        task.setOwnerName(director.getName());
        task.setName(procInst.getStateName());
        task.setTag(PROCESS_KEY);
        task.setFormKey(repair.getId().toString());
        task.addExtra("工单号", repair.getNo());
        task.addExtra("维修内容", repair.getContent());
        task.addExtra("设施设备", repair.getDeviceName());
        task.addExtra("创建人", repair.getCreateByName());
        taskService.addTask(task);
        task.setPath("/pages/repair/detail?taskId=" + task.getId());
        task.setPage("/repair-info.html?taskId=" + task.getId());
        taskService.saveTask(task);
        msgService.sendMsg(task.toMsg());
    }

    @Transactional(rollbackFor = Exception.class)
    public void complete(Integer taskId, Integer id, String completion)
    {
        //修改完善工单
        Repair repair = repairDao.findRepairById(id);
        repair.setCompletion(completion);
        repair.setCompleteTime(new Date());
        repair.setState(Repair.STATE_DOCUMENTED);
        repairDao.updateRepair(repair);
        //完成本次任务
        taskService.createAndCompleteTask(taskId);
        procInstService.next(repair.getProcInstId());
        //缺陷完成维修
        faultService.complete(repair.getFaultId());
    }

    /**
     * 撤销工单
     *
     * @param id 工单ID
     */
    @Transactional(rollbackFor = Exception.class)
    public void terminate(Integer id)
    {
        //修改工单
        Repair repair = repairDao.findRepairById(id);
        repair.setState(Repair.STATE_TERMINATED);
        repairDao.updateRepair(repair);
        //增加撤销流程信息
        User user = SubjectUtil.getUser();
        Task task = new Task();
        task.setProcInstId(repair.getProcInstId());
        task.setOwnerId(user.getId());
        task.setOwnerName(user.getName());
        task.setName("撤销工单");
        task.setTag(PROCESS_KEY);
        taskService.createAndCompleteTask(task);
        //终止流程
        procInstService.terminate(repair.getProcInstId());
    }

    public List<Repair> findTodayRepairs()
    {
        return repairDao.findTodayRepairs();
    }

    public Integer findTodayCompletedRepairsCount(Integer tunnelId)
    {
        return repairDao.findTodayCompletedRepairsCount(tunnelId);
    }

    public List<Repair> findRecentRepairs(Integer count)
    {
        return repairDao.findRecentRepairs(count);
    }

    public Integer findTodayRepairsTotalCount()
    {
        return repairDao.findTodayRepairsTotalCount();
    }

    public List<NameValue> statDailyRepairs(Integer days)
    {
        return repairDao.statDailyRepairs(days);
    }

    public String getRepairContents(Date date)
    {
        Map<String, Object> map = new HashMap<>();
        map.put("startDate", DateUtil.toDate(date));
        map.put("endDate", DateUtil.toDate(date));
        List<Repair> repairs = findRepairs(map);
        StringBuilder contentBuilder = new StringBuilder();
        for (int i = 0; i < repairs.size(); i++)
        {
            Repair repair = repairs.get(i);
            contentBuilder.append(repair.getContent() + "\n");
        }
        return contentBuilder.toString();
    }
}
